package org.example.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.example.handler.GlobalExceptionHandler;
import org.example.mapper.*;
import org.example.model.entity.*;
import org.example.model.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Queue;

@Component
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;
    @Autowired
    private PermissionMapper permissionMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        if(username == null|| username.trim().equals("")){
            throw new GlobalExceptionHandler.BusinessException("user.name.empty","用户名不能为空");
        }


        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name", username);
        UserDO userDO = userMapper.selectOne(queryWrapper);
        if (userDO == null) {
            throw new GlobalExceptionHandler.BusinessException("user.entity.empty","用户不存在");
        }
        LoginUser loginUser = new LoginUser(userDO);

        setAuthorities(loginUser,userDO.getId());
        // 1. 查询用户
        // 2. 判断密码是否正确
        // 3. 返回UserDetails对象
        return loginUser;
    }

    private void setAuthorities(LoginUser loginUser,Long userId) {
        List<UserRoleDO> userRoleDOs = userRoleMapper.selectList(
                new LambdaQueryWrapper<UserRoleDO>()
                        .eq(UserRoleDO::getUserId, userId)
        );
        if (userRoleDOs != null && !userRoleDOs.isEmpty()) {
            List<RolePermissionDO> rolePermissionDOS = rolePermissionMapper.selectList(new LambdaQueryWrapper<RolePermissionDO>()
                    .in(RolePermissionDO::getRoleId, userRoleDOs.stream().map(UserRoleDO::getRoleId).distinct().toList())

            );
            if (rolePermissionDOS != null && !rolePermissionDOS.isEmpty()) {
                List<PermissionDO> permissionDOS = permissionMapper.selectList(new LambdaQueryWrapper<PermissionDO>()
                        .in(PermissionDO::getId, rolePermissionDOS.stream().map(RolePermissionDO::getPermissionId).distinct().toList()));
                loginUser.setPermissions(permissionDOS.stream().map(PermissionDO::getPermissionCode).distinct().toList());
            }
        }
    }
}
